﻿using log4net.Appender;
using log4net.Core;
using Microsoft.Extensions.Configuration;
using MySql.Data.MySqlClient;
using System.Reflection;

namespace PmSoft.Logging;

public class MySQLAppender : AppenderSkeleton
{
    public static string? DbConnection { get; set; }

    private static Assembly assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly();
    public MySQLAppender()
    {
    }

    protected override void Append(LoggingEvent loggingEvent)
    {
        if (string.IsNullOrEmpty(DbConnection))
            return;
        string tableName = GetTableName(loggingEvent.Level);
        if (string.IsNullOrEmpty(tableName))
            return;
 
        try
        {
            using (var conn = new MySqlConnection(DbConnection))
            {
                var sqlCommandText = $@"INSERT INTO {tableName} (app_name, date, logger,message) VALUES (@AppName, @Date, @Logger,@Message);";

                using (var command = new MySqlCommand(sqlCommandText, conn))
                {
                    command.Parameters.AddWithValue("@Message", RenderLoggingEvent(loggingEvent));
                    command.Parameters.AddWithValue("@AppName", assembly.GetName().Name);
                    command.Parameters.AddWithValue("@Date", loggingEvent.TimeStamp);
                    command.Parameters.AddWithValue("@Logger", loggingEvent.LoggerName);
                    conn.Open();
                    command.ExecuteNonQuery();
                }
            }
        }
        catch (Exception ex)
        {
            ErrorHandler.Error("Failed to write log entry into the database.", ex);
        }
    }

    protected override bool RequiresLayout => true;

    protected override void OnClose()
    {
        base.OnClose();
    }

    private string GetTableName(Level level)
    {
        return level.Name switch
        {
            "DEBUG" => "log4net_debug",
            "INFO" => "log4net_info",
            "WARN" => "log4net_warning",
            "ERROR" => "log4net_error",
            _ => string.Empty
        };
    }

}
